import React, {useEffect, useState} from 'react';
import makeStyles from "@material-ui/core/styles/makeStyles";
import Grid from "@material-ui/core/Grid";
import axios from 'axios'
import {LIMIT, SERVER_ERROR_MESSAGE} from "../constants";
import Fab from '@material-ui/core/Fab';
import KeyboardArrowUpIcon from '@material-ui/icons/KeyboardArrowUp';
import Tooltip from '@material-ui/core/Tooltip';
import useScrollTrigger from '@material-ui/core/useScrollTrigger';
import Zoom from '@material-ui/core/Zoom'
import InfiniteScroll from 'react-infinite-scroll-component';
import LoadingSpinner from "../components/LoadingSpinner";
import InlineError from "../components/InlineError";
import EmptyResultsMessages from "../components/EmptyResultsMessages";
import BaseBookList from "./BaseBookList";

const useStyles = makeStyles(theme => ({
    root: {
        padding: theme.spacing(2)
    },
    scrollTop: {
        position: 'fixed',
        bottom: theme.spacing(4),
        right: theme.spacing(50),
        [theme.breakpoints.down('sm')]: {
            bottom: theme.spacing(4),
            right: theme.spacing(2),
        }
    },
}))

function ScrollTop(props) {
    // const {children, window} = props;
    const {children} = props;
    const classes = useStyles();
    // // Note that you normally won't need to set the window ref as useScrollTrigger
    // // will default to window.
    // // This is only being set here because the demo is in an iframe.
    const trigger = useScrollTrigger({
        // target: window ? window() : undefined,
        disableHysteresis: true,
        threshold: 100,
    });

    const handleClick = (event) => {
        const anchor = (event.target.ownerDocument || document).querySelector('#back-to-top-anchor');

        if (anchor) {
            anchor.scrollIntoView({behavior: 'smooth', block: 'center'});
        }
    };

    return (
        <Zoom in={trigger}>
            <div onClick={handleClick} role="presentation" className={classes.scrollTop}>
                {children}
            </div>
        </Zoom>
    );
}

export default function BaseQueryBooks(props) {
    const classes = useStyles()

    const [books, setBooks] = useState([])
    const [error, setError] = useState('')
    const [loading, setLoading] = useState(true)
    const [more, setMore] = useState(true)
    const [offset, setOffset] = useState(0)

    const {url} = props

    async function fetchBooks(url) {

        try {
            setLoading(true)
            setMore(true)
            setOffset(0)

            const response = await axios.get(url)
            setLoading(false)
            setBooks(await response.data)

        } catch (err) {
            setLoading(false)
            setBooks([])  //置为空防意外?
            if (err.response && err.response.status === 404)
                setError(err.response.data['detail'])
                // setError('您访问的页面不存在!')
            else
                setError(SERVER_ERROR_MESSAGE)
        }
    }

    // 切换分类名(categoryName)时才执行，不依赖于offset
    // url改变时把offset设置为0
    useEffect( () => {
        fetchBooks(`${url}`)
    }, [url])


    // const url = `${BASE_URL}/${categoryName}/books/`
    // const url = `${BASE_URL}/search/?keyword=${keyword}`
    // TODO:出现多个??,urlencode???

    async function fetchMoreBooks(url) {
        try {
            const response = await axios.get(url)
            setLoading(false)
            const newData = await response.data
            if (newData.length === 0) {// 所有元素加载完成
                setMore(false)
            } else {
                setBooks(prevState => [...prevState, ...newData])
            }

        } catch (err) {
            setLoading(false)
            setBooks([])  //置为空防意外?
            if (err.response && err.response.status === 404)
                setError(err.response.data['detail'])
                // setError('您访问的页面不存在!')
            else
                setError(SERVER_ERROR_MESSAGE)
        }
    }

    // 只依赖offset,在页面滚动到最后一个节点的时候才执行
    useEffect(() => {
        if (offset > 0) {
            // limit需要和后端代码保持一致??limit是固定值
            fetchMoreBooks(`${url}?limit=${LIMIT}&offset=${offset}`)
        }
    }, [offset])

    if (loading) return <div className={classes.root}><LoadingSpinner/></div>
    if (error) return <div className={classes.root}><InlineError error={error}/></div>
    if (books.length === 0) return <div className={classes.root}><EmptyResultsMessages/></div>

    return (
        <>
            <InfiniteScroll
                dataLength={books.length} //This is important field to render the next data
                next={() => setOffset(offset + 5)}
                hasMore={more}
                loader={(<div className={classes.root}>...</div>)}
                scrollThreshold={1}
            >
                <BaseBookList books={books}/>
            </InfiniteScroll>

            <Grid container justifyContent="center" alignItems="center">
                <ScrollTop {...props}>
                    <Tooltip title="返回顶部" placement="top">
                        <Fab color="inherit" size="small">
                            <KeyboardArrowUpIcon/>
                        </Fab>
                    </Tooltip>
                </ScrollTop>
            </Grid>
        </>
    )
};
